from flask import request, jsonify
from managers.nodes.baseGraphNode import BaseGraphNode
from .sessionInfo import SessionInfo
from ..execute.baseExeHis import BaseExeHis
import json

class RequestGraphNode(BaseGraphNode):
    """
    客户端访问即返回的“即时响应”节点。
    不依赖上游，不触发下游。
    """
    def __init__(self, id: str, data: dict, graphNodeManager, random_key: str):
        super().__init__(id, data, graphNodeManager, random_key)
        # 前端配置
        self.method = data['data'].get('method', 'GET').upper()          # 允许的方法
        self.route = data['data']['route']                               # 必填，如 /health
        self.resp_status = data['data'].get('status', 200)               # HTTP 状态码
        self.resp_headers = data['data'].get('headers', {})              # 自定义头
        self.resp_body = data['data'].get('body', '')                    # 返回内容
        self.resp_content_type = data['data'].get('contentType', 'text/plain')
        self.running = False

    # ---------- 部署时注册路由 ----------
    def execute(self, session_info: SessionInfo = None,
                exe_his: BaseExeHis = None, trigger=None, running_id=None):
        if self.running:          # 已注册过
            return
        self.running = True

        from flask import current_app as app

        def _handler():
            # 方法校验
            if request.method != self.method:
                return 'Method Not Allowed', 405
            # 构造响应
            headers = {'Content-Type': self.resp_content_type}
            headers.update(self.resp_headers)
            return self.resp_body, self.resp_status, headers #return Response(self.resp_body, status=self.resp_status, headers=headers)

        # 动态挂到 Flask 路由表
        rule = f'/runtime/request/{self.route}'
        app.add_url_rule(rule,
                         endpoint=f'request_node_{self.id}',
                         view_func=_handler,
                         methods=[self.method]) #add_url_rule(rule, endpoint=None, view_func=None, methods=None, **options)
        print(f'RequestNode "{self.name}" listening on {rule}  method={self.method}')

    # ---------- 停止时卸掉路由 ----------
    def stop(self):
        if not self.running:
            return
        self.running = False
        rule = f'/runtime/request/{self.route}'
        app = self.graphNodeManager.http_node.app
        app.url_map._rules_by_endpoint.pop(f'request_node_{self.id}', None)
        # Flask >=2.2 可用 app.view_functions.pop(...)
        print(f'RequestNode "{self.name}" route removed')